/**
 * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springblade.modules.system.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.core.boot.tenant.TenantId;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.DigestUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.system.entity.*;
import org.springblade.modules.system.mapper.DeptMapper;
import org.springblade.modules.system.mapper.RoleMapper;
import org.springblade.modules.system.mapper.TenantMapper;
import org.springblade.modules.system.mapper.UserMapper;
import org.springblade.modules.system.service.IPostService;
import org.springblade.modules.system.service.ITenantService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author Chill
 */
@Service
@AllArgsConstructor
public class TenantServiceImpl extends BaseServiceImpl<TenantMapper, Tenant> implements ITenantService {

	private final TenantId tenantId;
	private final RoleMapper roleMapper;
	private final DeptMapper deptMapper;
	private final IPostService postService;
	private final UserMapper userMapper;

	@Override
	public IPage<Tenant> selectTenantPage(IPage<Tenant> page, Tenant tenant) {
		return page.setRecords(baseMapper.selectTenantPage(page, tenant));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean saveTenant(Tenant tenant) {
		if (Func.isEmpty(tenant.getId())) {
			List<Tenant> tenants = baseMapper.selectList(Wrappers.<Tenant>query().lambda().eq(Tenant::getIsDeleted, BladeConstant.DB_NOT_DELETED));
			List<String> codes = tenants.stream().map(Tenant::getTenantId).collect(Collectors.toList());
			String tenantId = getTenantId(codes);
			tenant.setTenantId(tenantId);
			super.saveOrUpdate(tenant);
			// 新建租户对应的默认管理用户
			User user = new User();
			user.setTenantId(tenantId);
			user.setName(tenant.getTenantName());
			user.setRealName(tenant.getTenantName());
			user.setAccount(tenant.getTenantName() + "_" + tenantId);
			user.setPassword(DigestUtil.encrypt("Aa123456"));
			List<Role> adminRoles = roleMapper.selectList(Wrappers.<Role>lambdaQuery().eq(Role::getRoleAlias, "s_admin"));
			user.setRoleId(String.valueOf(adminRoles.get(0).getId()));
			user.setBirthday(new Date());
			user.setSex(1);
			user.setIsDeleted(BladeConstant.DB_NOT_DELETED);
			userMapper.insert(user);
		}
		return super.saveOrUpdate(tenant);
	}

	@Override
	public User addTenant(String userName, String password) {
		List<Tenant> tenants = baseMapper.selectList(Wrappers.<Tenant>query().lambda().eq(Tenant::getIsDeleted, BladeConstant.DB_NOT_DELETED));
		List<String> codes = tenants.stream().map(Tenant::getTenantId).collect(Collectors.toList());
		String tenantId = getTenantId(codes);
		Tenant tenant = new Tenant();
		tenant.setTenantId(tenantId);
		tenant.setTenantName(userName);
		super.saveOrUpdate(tenant);
		// 新建租户对应的默认管理用户
		User user = new User();
		user.setTenantId(tenantId);
		user.setName(userName);
		user.setRealName(userName);
		user.setAccount(userName);
		user.setPassword(DigestUtil.encrypt(password));
		List<Role> adminRoles = roleMapper.selectList(Wrappers.<Role>lambdaQuery().eq(Role::getRoleAlias, "s_admin"));
		user.setRoleId(String.valueOf(adminRoles.get(0).getId()));
		user.setBirthday(new Date());
		user.setSex(1);
		user.setIsDeleted(BladeConstant.DB_NOT_DELETED);
		userMapper.insert(user);
		return user;
	}

	private String getTenantId(List<String> codes) {
		String code = tenantId.generate();
		if (codes.contains(code)) {
			return getTenantId(codes);
		}
		return code;
	}

}
